package com.mobile.common.base.hibernate;

import java.io.Serializable;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Assert;

import com.mobile.common.util.DAOUtil;

/**
 * 
 * @author qingqiu
 *
 * @param <T>对象的类型
 * @param <PK>主键
 */

@SuppressWarnings({"rawtypes","unchecked"})
public abstract class HibernateDao<T, PK extends Serializable> {
	
	public abstract SessionFactory getSessionFactory();
	
	public Session getSession(){
		return getSessionFactory().getCurrentSession();
	}
	public HibernateDao() {
		LOG = LoggerFactory.getLogger(getClass());
		//*****子类初始化时，容易出错，entityClass可能为null！
		this.entityClass = (Class<T>)DAOUtil.getTypeArguments(HibernateDao.class, this.getClass()).get(0);
	}
	public HibernateDao(Class<T> entityClass) {
		LOG = LoggerFactory.getLogger(getClass());
		this.entityClass = entityClass;
	}

	public Object load(Serializable id) {
		Assert.notNull(id, "id不能为空");
		return getSession().load(entityClass, id);
	}

	public Object get(Serializable id) {
		Assert.notNull(id, "id不能为空");
		return getSession().get(entityClass, id);
	}

	public void save(Object entity) {
		Assert.notNull(entity, "entity不能为空");
		getSession().saveOrUpdate(entity);
		LOG.debug("save entity: {}", entity);
	}

	public void merge(Object entity) {
		Assert.notNull(entity, "entity不能为空");
		getSession().merge(entity);
		LOG.debug("merge entity: {}", entity);
	}

	public void destroy(Object entity) {
		Assert.notNull(entity, "entity不能为空");
		getSession().delete(entity);
		LOG.debug("delete entity: {}", entity);
	}

	public void destroy(Serializable id) {
		Assert.notNull(id, "id不能为空");
		getSession().delete(load(id));
		LOG.debug("delete entity {},id is {}", entityClass.getSimpleName(), id);
	}

	public void destoryAll(Collection entities) {
		if (entities == null)
			return;
		Object entity;
		for (Iterator iterator = entities.iterator(); iterator.hasNext(); 
			getSession().delete(entity))
			entity = iterator.next();
	}

	public List findAll() {
		return find(new Criterion[0]);
	}

	public List findAll(String orderBy, boolean isAsc) {
		Criteria c = createCriteria(new Criterion[0]);
		if (isAsc)
			c.addOrder(Order.asc(orderBy));
		else
			c.addOrder(Order.desc(orderBy));
		return c.list();
	}

	public List findBy(String propertyName, Object value) {
		Assert.hasText(propertyName, "propertyName不能为空");
		Criterion criterion = Restrictions.eq(propertyName, value);
		return find(new Criterion[] { criterion });
	}
	public List find(Criterion criterions[]) {
		return createCriteria(criterions).list();
	}

	public Criteria createCriteria(Criterion...criterions) {
		Criteria criteria = getSession().createCriteria(entityClass);
		Criterion acriterion[];
		int j = (acriterion = criterions).length;
		for (int i = 0; i < j; i++) {
			Criterion c = acriterion[i];
			criteria.add(c);
		}
		return criteria;
	}

	//---------------------------------------------------------
	protected final Logger LOG;
	protected Class<T> entityClass;
}